<template>
	<el-card class="menu-tree" id="node-tree">
		<div slot="header" class="card-label">
			<span>{{$t(header)}}</span>
			<div v-show="showButton" class="icon-button">
				<el-button circle icon="el-icon-plus" size="small" type="primary" @click="appendMainNode"></el-button>
			</div>
		</div>
		<div class="down-tree">
			<el-tree ref="tree" :allow-drag="allowDragNode" :data="data" :default-expanded-keys="defaultExpanded" :draggable="isDraggable" node-key="id"
				:load="loadNode" :props="defaultProps" :show-checkbox="showCheck" auto-expand-parent expand-on-click-node :lazy="lazy" @node-expand="expandNode"
				@node-drop="handleDrop" :allow-drop="allowDropNode" accordion highlight-current>
				<template v-slot="{node, data}">
					<span class="custom-tree-node" @click="() => editNode(node, data)">
						<span><e-icon :icon-name="data.icon"></e-icon>{{$t(data.name)}}</span>
						<span v-show="showButton">
							<el-button v-show="showLeft(node,data)" circle icon="el-icon-plus" size="mini" style="margin-left: 5px;"
								type="primary" @click="() => append(node, data)"></el-button>
							<el-button v-show="showRight(node,data)" circle icon="el-icon-minus" size="mini" style="margin-left: 5px;"
								type="danger" @click="() => remove(node, data)">
							</el-button>
						</span>
					</span>
				</template>
			</el-tree>
		</div>
	</el-card>
</template>

<script>
export default {
	name: "node-tree",
	props: {
		header: {
			type: String,
			default: ""
		},
		data: {
			type: Array,
			default() {
				return [];
			},
			validator: (value) => {
				return value.length > 0;
			}
		},
		lazy: {
			type: Boolean,
			default: true
		},
		showCheck: {
			type: Boolean,
			default: false
		},
		isDraggable: {
			type: Boolean,
			default: true
		},
		showButton: {
			type: Boolean,
			default: false
		},
		showAppend: {
			type: Function
		},
		showRemove: {
			type: Function
		},
		allowDrag: {
			type: Function
		},
		allowDrop: {
			type: Function
		}
	},
	data() {
		return {
			timer: null,
			defaultExpanded: this.envMode !== "production" ? [1] : [],
			defaultProps: {
				children: "children",
				isLeaf: (data, node) => {
					return !data.hasChildren && !data.children;
				}
			}
		};
	},
	methods: {
		showLeft(node, data) {
			if (this.showAppend) {
				return this.showAppend(node, data);
			}
			return true;
		},
		showRight(node, data) {
			if (this.showRemove) {
				return this.showRemove(node, data);
			}
			return true;
		},
		allowDragNode(draggingNode) {
			if (this.allowDrag) {
				return this.allowDrag(draggingNode);
			}
			return true;
		},
		allowDropNode(draggingNode, dropNode, type) {
			if (this.allowDrop) {
				return this.allowDrop(draggingNode, dropNode, type);
			}
			return true;
		},
		append(node, data) {
			this.$emit("handle-append", node, data);
		},
		appendMainNode() {
			this.$emit("handle-append-main");
		},
		editNode(node, data) {
			this.$emit("handle-edit", node, data);
		},
		expandNode(data, node, current) {
			this.editNode(node, data);
		},
		remove(node, data) {
			this.$emit("handle-remove", node, data);
		},
		setActivedNode(node) {
			this.$nextTick(() => {
				this.timer = setTimeout(() => {
					if (this.$refs.tree) {
						this.$refs.tree.setCurrentKey(node.id);
					}
				}, 200);
			});
		},
		loadNode(node, resolve) {
			console.log("Lazy load menus tree successfully !", node.data);
			if (Array.isArray(node.data)) {
				resolve(node.data);
				return;
			}
			if (node.data.hasChildren && node.data.children.length > 0) {
				this.timer = setTimeout(() => {
					resolve(node.data.children);
				}, 200);
			}
		},
		// 拖拽事件 参数依次为：被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置（before、after、inner）、event
		handleDrop: async (draggingNode, dropNode, dropType, event) => {
			// 当拖拽类型不为inner,说明只是同级或者跨级排序，只需要寻找目标节点的父ID，获取其对象以及所有的子节点，并为子节点设置当前对象的ID为父ID即可
			// 当拖拽类型为inner，说明拖拽节点成为了目标节点的子节点，只需要获取目标节点对象即可
			const dropData = dropType !== "inner" ? dropNode.parent.data : dropNode.data;
			const nodeData = (dropNode.level === 1 && dropType !== "inner") ? dropData : dropData.children;
			// 设置父ID,当level为1说明在第一级，pid为空
			nodeData.forEach(element => element.pid = dropData.id);
			//为树形数据id重新排序
			const sortTree = (parent, array) => {
				if (array && array.length > 0) {
					array.forEach((item, index) => {
						if (item.id) {
							item.id = parent ? parent.id + "-" + (index + 1) : (index + 1);
							sortTree(item, item.children);
						}
					});
				}
			};
			sortTree(dropNode.level === 1 ? null : dropData, nodeData);
			console.log(nodeData);
		}
	},
	beforeDestroy() {
		if (this.timer) {
			clearTimeout(this.timer); // 在Vue实例销毁前，清除我们的定时器
		}
	}
};
</script>

<style scoped>
#node-tree .el-card {
	background-color: #F5F5F5;
}

#node-tree >>> .el-card__header {
	padding: 10px 16px;
	font-size: 18px;
	font-weight: bold;
}

#node-tree >>> .el-card__body {
	padding: 1px 10px 10px 5px;
}

.down-tree {
	height: calc(76.9vh);
	display: block;
	padding-right: 5px;
	margin-right: -8px;
	overflow-y: auto;
	overflow-x: hidden;
}

.down-tree .el-tree {
	background-color: #F5F5F5;
}

.icon-button {
	float: right;
	margin-top: -5px;
	margin-right: -10px;
}

.menu-tree {
	height: calc(81.4vh);
}

.menu-tree >>> .el-tree--highlight-current .el-tree-node.is-expanded > .el-tree-node__content {
	background-color: #A8CFF5;
}

.menu-tree >>> .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
	background-color: #BBB1EA;
}

.menu-tree >>> .el-tree-node__expand-icon {
	font-size: 20px;
}

.menu-tree >>> .el-tree-node__content {
	height: 30px;
}

.menu-tree >>> .el-tree-node__content:hover {
	background-color: #DED6D6 !important;
}

.menu-tree >>> .el-tree .el-icon-caret-right {
	display: block;
	font-size: 20px;
	background-size: 20px;
}

.menu-tree >>> .el-tree .el-icon-caret-right::before {
	color: #3F3D3D;
}

.menu-tree >>> .el-tree .el-tree-node__expand-icon.is-leaf::before {
	opacity: 0;
}

.custom-tree-node {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	font-size: 14px;
}

.custom-tree-node span {
	font-size: 14px;
}

.custom-tree-node i, svg {
	margin-left: 5px;
	margin-right: 10px;
	font-size: 17px;
}

.custom-tree-node .fa {
	margin-left: 6px;
	margin-right: 10px;
	font-size: 15px;
}

.custom-tree-node .fa.fa-car {
	margin-left: 5px;
	margin-right: 10px;
	font-size: 14px;
}

.menu-class {
	margin-right: 15px;
}

</style>
